#!/usr/bin/python3

# SPDX-FileCopyrightText: Red Hat, Inc.
# SPDX-License-Identifier: GPL-2.0-or-later

"""
Usage: logdb dbname logfile ...

Import vdsm log files into log database dbname.
"""

from __future__ import absolute_import
from __future__ import print_function

import sqlite3
import sys


CREATE_TABLE = """
create table if not exists messages(
    timestamp datetime,
    level text,
    logger text,
    thread text,
    module text,
    lineno int,
    func text,
    text text
);
"""

DROP_INDEXES = """
drop index if exists timestamp;
drop index if exists level;
drop index if exists thread;
drop index if exists module;
drop index if exists func;
"""

CREATE_INDEXES = """
create index timestamp on messages (timestamp);
create index level on messages (level);
create index thread on messages (thread);
create index module on messages (module);
create index func on messages (func);
"""


def main(args):
    if len(args) < 2:
        print(__doc__)
        sys.exit(2)

    dbname = args.pop(0)
    with sqlite3.connect(dbname) as con:
        con.execute(CREATE_TABLE)
        con.executescript(DROP_INDEXES)
        for logfile in args:
            with open(logfile) as f:
                for msg in parse(f):
                    con.execute("insert into messages values "
                                "(?,?,?,?,?,?,?,?)", msg)
        con.executescript(CREATE_INDEXES)
        con.commit()


def parse(logfile):
    msg = None
    for line in logfile:
        line = line.rstrip()
        try:
            # thread::level::timestamp::module::lineno::logger::(func) message
            thread, level, timestamp, module, lineno, logger, rest = \
                line.split("::", 6)
        except ValueError:
            # Some message text has multiple lines
            if msg:
                msg[-1] += "\n" + line
        else:
            # Y-m-d H-M-S,msec -> Y-m-d H-M-S.msec
            timestamp = timestamp.replace(",", ".")
            # (func) text
            try:
                func, text = rest.split(" ", 1)
            except ValueError:
                func, text = rest, ""
            func = func[1:-1]
            if msg:
                yield tuple(msg)
            msg = [timestamp, level, logger, thread, module, lineno, func,
                   text]
    if msg:
        yield tuple(msg)


if __name__ == "__main__":
    main(sys.argv[1:])
